// Calculation_Abilities.cpp: Implementierungsdatei
//

#include "stdafx.h"
#include "Charplan.h"
#include "Calculation_Break.h"
#include "LuaInterface.h"
#include "Charplandoc.h"


IMPLEMENT_DYNCREATE(CCalculation_Break, CCalculationPage)

CCalculation_Break::CCalculation_Break(CWnd* pParent /*=NULL*/)
        : CCalculationPage(pParent)
{
}

// for runtime creations
BOOL CCalculation_Break::Create(CWnd* pParentWnd)
{
    return CDialog::Create(CCalculation_Break::IDD,pParentWnd);
}

CCalculation_Break::~CCalculation_Break()
{
}

void CCalculation_Break::DoDataExchange(CDataExchange* pDX)
{
    CCalculationPage::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_LIST2, wnd_list);
    DDX_Control(pDX, IDC_LINK, wnd_link);
}


BEGIN_MESSAGE_MAP(CCalculation_Break, CCalculationPage)
END_MESSAGE_MAP()


BOOL CCalculation_Break::OnInitDialog()
{
    CCalculationPage::OnInitDialog();

	wnd_list.InsertColumn(0,_T("Name"));
	wnd_list.InsertColumn(1,_T("Cast"));
	wnd_list.InsertColumn(2,_T("cur."));
	wnd_list.InsertColumn(3,_T("next"));

    FillList();
    return TRUE;
}

void CCalculation_Break::OnPointsChanged()
{
    FillList();
}

void CCalculation_Break::OnLevelChanged()
{
    FillList();
}

int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
    return (int)(lParam1-lParam2);
}

void    CCalculation_Break::FillList()
{
    int dex = GetFinalDex();

    wnd_list.DeleteAllItems();

    CStringArray spelllines;
    gdbinterface.GetListOfSpellLines(spelllines);

    // base
    int level = (int)(GetDocument()->GetLevel());

    for (int t=0;t<spelllines.GetCount();t++)
	{
		gdbinterface.SelectSpellLine(spelllines[t]);

        CStringArray spellcats;
        CStringArray spells;
        IntArray	 spell_levels;
        IntArray	 spell_ids;


		gdbinterface.GetListOfSpellCatsBase(spellcats);
		for (int t2=0;t2<spellcats.GetCount();t2++)
		{
			gdbinterface.SelectSpellCatBase(spellcats[t2]);
			gdbinterface.GetListOfSpells(&spells,&spell_levels,&spell_ids);

            AddHighestSpell(spellcats[t2], spell_ids, spell_levels, level,dex);
        }

        int spec_level = GetDocument()->GetSpecLevel(spelllines[t]);
        gdbinterface.GetListOfSpellCatsSpec(spellcats);
		for (int t2=0;t2<spellcats.GetCount();t2++)
		{
			gdbinterface.SelectSpellCatSpec(spellcats[t2]);
			gdbinterface.GetListOfSpells(&spells,&spell_levels,&spell_ids);

            AddHighestSpell(spellcats[t2], spell_ids, spell_levels, spec_level ,dex);
        }
    }

    wnd_list.SetColumnWidth(0,LVSCW_AUTOSIZE);
    wnd_list.SetColumnWidth(1,LVSCW_AUTOSIZE);
    wnd_list.SetColumnWidth(2,LVSCW_AUTOSIZE);
    wnd_list.SetColumnWidth(3,LVSCW_AUTOSIZE);
    wnd_list.SortItems(CompareFunc,NULL);
}


void    CCalculation_Break::AddHighestSpell(const CString& cat, IntArray& spell_ids, IntArray& spell_levels, int level,int dex)
{
    int index=0;
    for (;index<spell_levels.GetCount() && spell_levels[index]<=level;++index);
    if (index==0) return;
    --index;

    gdbinterface.SelectSpellID(spell_ids[index]);

    CStringArray properties_names;
    CStringArray properties_vals;

    gdbinterface.GetSpellDescription(properties_names, properties_vals);
    int casttime = (int)(1000*atof(properties_vals[3]));

    if (casttime>0)   AddSpell(cat,casttime,dex);
}


void    CCalculation_Break::AddSpell(const CString& name, int casttime_ms, int cur_dex)
{
    std::map<int, int*> dex_break;
    int t1[] ={337,344,392,0};  dex_break[2000]=t1;
    int t2[] ={308,354,356,0};  dex_break[2100]=t2;
    int t3[] ={320,368,374,0};  dex_break[2200]=t3;
    int t4[] ={332,380,386,0};  dex_break[2300]=t4;
    int t5[] ={307,350,392,0};  dex_break[2400]=t5;
    int t6[] ={319,362,0};      dex_break[2500]=t6;
    int t7[] ={332,374,0};      dex_break[2600]=t7;
    int t8[] ={344,386,0};      dex_break[2700]=t8;
    int t9[] ={320,356,392,0};  dex_break[2800]=t9;
    int t10[]={332,362,368,0};  dex_break[2900]=t10;
    int t11[]={338,374,0};      dex_break[3000]=t11;
    int t12[]={326,356,0};      dex_break[3500]=t12;

    int idx = wnd_list.InsertItem(wnd_list.GetItemCount(),name);
    wnd_list.SetItemData(idx,(LPARAM)(casttime_ms));
    CString casttime_str;
    casttime_str.Format("%1.1f",casttime_ms/1000.0);
    wnd_list.SetItem(idx,1,LVIF_TEXT,casttime_str,0,0,0,NULL);

    std::map<int, int*>::const_iterator dex_tab=dex_break.find(casttime_ms);

    if (dex_tab != dex_break.end())
    {
        CString left,right;
        CString temp;

        int* run=dex_tab->second;
        while (*run)
        {
            temp.Format("%i ",*run);
            if ((*run)<=cur_dex) left += temp;
            else                right +=temp;
            ++run;
        }

        wnd_list.SetItem(idx,2,LVIF_TEXT,left,0,0,0,NULL);
        wnd_list.SetItem(idx,3,LVIF_TEXT,right,0,0,0,NULL);
    }
}

int    CCalculation_Break::GetFinalDex()
{
    CCharplanDoc* pdoc = GetDocument();
    if (!pdoc) return 0;

    int stats[8];
    pdoc->GetStatsFinal(stats);

    int dex = stats[2];

   
    // User option
    int cap_item=0, cap_item_ovr=0, cap_buff_base=0, cap_buff_spec=0, cap_buff_spec_int=0;
    if (pdoc->p_lua)
    {
        int t_caps = pdoc->p_lua->OpenTable("cap",8);
            pdoc->p_lua->GetVar("item_bonus",cap_item,t_caps);
            pdoc->p_lua->GetVar("item_bonus_overcap",cap_item_ovr,t_caps);
            pdoc->p_lua->GetVar("buff_bonus_base",cap_buff_base,t_caps);
            pdoc->p_lua->GetVar("buff_bonus_spec",cap_buff_spec,t_caps);
            pdoc->p_lua->GetVar("buff_bonus_spec_int",cap_buff_spec_int,t_caps);
        pdoc->p_lua->CloseTable();
    }

    dex += pdoc->GetOption(_T("BI_2"),cap_item);
    dex += pdoc->GetOption(_T("BICAP_2"),cap_item_ovr);
    dex += pdoc->GetOption(_T("BB_2"),cap_buff_base);
    dex += pdoc->GetOption(_T("BBS_2"),cap_buff_spec);


	int	mytic_item_buff = pdoc->GetOption(_T("MYTIC_ITEM"),-1);
	int	mytic_item_value = pdoc->GetOption(_T("MI_VAL"),0);
	int	mytic_item_cap = pdoc->GetOption(_T("MI_VAL_CAP"),0);

	if (mytic_item_buff==2 && (mytic_item_value>0 || mytic_item_cap>0))
	{
        dex += mytic_item_value+mytic_item_cap;
	}

    return dex;
}
